﻿using System.Threading.Tasks;
using System;
using System.IO;
using Microsoft.VisualStudio.Threading;

namespace QuickShare.Vsix.SqlList.Commons
{
    public class Command
    {
        public string Target { get; private set; }
        public string Args { get; private set; }
        public CommandResult Run()
        {
            var logPath = Path.Combine(LogDir, "logs");
            Helper.TryCreateDir(logPath);
            var file = Path.Combine(logPath, $"log-{DateTime.Today:yyyyMMdd}.log");
            var msg = $"{DateTime.Now:HH:mm:ss.fff} 执行命令：\r\n{Target} {Args}";
            File.AppendAllText(file, msg);
            try
            {
                using(System.Diagnostics.Process process = new System.Diagnostics.Process())
                {
                    var text = "";
                    var error = "";
                    process.StartInfo.FileName = Target;
                    process.StartInfo.Arguments = Args;
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardInput = true;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.RedirectStandardError = true;
                    process.StartInfo.CreateNoWindow = true;
                    process.OutputDataReceived += (s, e) => text += "\r\n" + e.Data;
                    process.ErrorDataReceived += (s, e) => error += "\r\n" + e.Data;
                    process.Start();
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();
                    process.WaitForExit();
                    text = text.Trim();
                    error = error.Trim();
                    if(!string.IsNullOrWhiteSpace(text))
                    {
                        msg = $"\r\n{DateTime.Now:HH:mm:ss.fff} 执行结果：\r\n{text}";
                        File.AppendAllText(file, msg);
                    }
                    if(!string.IsNullOrWhiteSpace(error))
                    {
                        msg = $"\r\n{DateTime.Now:HH:mm:ss.fff} 错误信息：\r\n{error}";
                        File.AppendAllText(file, msg);
                        return CommandResult.Fail(error);
                    }
                    return CommandResult.Success(text);
                }
            }
            catch(Exception ex)
            {
                msg = $"\r\n{DateTime.Now:HH:mm:ss.fff} 执行错误：{ex.Message}\r\n堆栈信息:{ex.StackTrace}";
                File.AppendAllText(file, msg);
                return CommandResult.Error(ex.Message);
            }
            finally
            {
                msg = "\r\n--------------------------------------------------------------\r\n";
                File.AppendAllText(file, msg);
            }
        }

        public async Task<CommandResult> RunAsync()
        {
            return await Task.Run(() => this.Run());
        }

        internal static string LogDir { get; set; }

        public static async Task<CommandResult> RunAsync(string target, string args)
        {
            var cmd = new Command { Target = target, Args = args };
            return await cmd.RunAsync();
        }
    }
}
